Image = 靜態模板(像 App 安裝檔)
Container = 活動中的實體(像跑起來的 App)
Image 會包含你專案內的檔案,只要被 Dockerfile 中的 COPY 或 ADD 指令打包進去的內容都會存在於 image 中。
不會包含 | 說明 |
---|---|
.env 或 gitignored 文件 | 除非你有 COPY 它進 image |
volume 掛載的資料 | 像 MySQL 的資料,如果掛在 volume,只會存在 volume,不會進 image 裡 |
運行中動態產生的檔案 | 不會寫進 image,這是容器層級的變化 |
指令 | 功能 |
---|---|
docker images |
查看本機有哪些Images |
docker run -d -p 8080:80 nginx |
用 nginx Image 快速建立一個 Container |
docker ps |
查看現在運行的 Containers |
docker stop <容器ID或名字> |
停止容器 |
docker rm <容器ID或名字> |
刪除容器 |
如果不設定 Volume,容器內資料會:
容器重啟、容器刪除 -> 資料遺失消失
這在開發或生產環境都非常致命(想像你的 MySQL 資料庫一重啟就變空白🤣)
所以學會 Volume,是做任何正式 Docker 專案必學技能!
指令 | 功能 |
---|---|
docker volume create <自己取> |
建立Volume |
docker volume ls |
查看目前有哪些Volume |
docker run -d -p 8081:80 -v mydata:/usr/share/nginx/html nginx |
用Volume 綁定啟動容器 |
備註:docker run -d -p 8081:80 -v mydata:/usr/share/nginx/html nginx
指令拆解
部份 | 說明 |
---|---|
docker run |
啟動一個容器 |
-d |
背景執行 |
-p 8081:80 |
將本機的8081 port 綁到容器內部的80 port(nginx預設的port) |
-v mydata:/usr/share/nginx/html |
將 Volume mydata 掛載到容器的 /usr/share/nginx/html 資料夾 |
nginx |
使用 nginx 官方image |
以上三個指令完成,成功的話用docker volume inspect mydata
可以看到以下畫面:
nginx 預設會讀取 /usr/share/nginx/html 作為網站資料夾。
但我們用 Volume 把這個資料夾綁出去 ➔ 變成跟本地 mydata 連在一起。
以後只要修改 Volume 裡的內容,就可以直接改網站,不用重啟容器!
好的,現在我們來看看資料是不是不會消失
首先,我們先進入容器docker exec -it 容器ID bash
接著,到nginx網頁資料夾cd /usr/share/nginx/html
再來,建立一個新的index.htmlecho "Hello Hi Hi Docker Volume!" > index.html
現在打開瀏覽器輸入 http://localhost:8081 會在頁面上看到 Hello Hi Hi Docker Volume!
來實驗看看了!!
首先,刪掉 nginx 容器,但不刪 Volume
Step1:刪除容器docker stop 容器ID docker rm 容器ID
Step2: 用同樣的Volume 再跑一次nginxdocker run -d -p 8081:80 -v mydata:/usr/share/nginx/html nginx
Step3:再打開http://localhost:8081
會發現網頁還是Hello Hi Hi Docker Volume!
(容器被刪掉了,但是資料還在!!)
整理上面的指令:
指令 | 功能 |
---|---|
docker volume create <自己取> |
建立Volume |
docker volume ls |
查看目前有哪些Volume |
docker run -d -p 8081:80 -v mydata:/usr/share/nginx/html nginx |
用Volume 綁定啟動容器 |
docker exec -it 容器ID bash |
進入容器 |
echo "文字" > 檔案 |
修改內容 |
docker stop ->docker rm |
刪除容器但保留Volume |
備註:
docker volume rm mydata
,不然資料會持續存在Step1: 建立一個Volumedocker volume create mysql_data
Step2: pull MySQL 官方 Imagedocker pull mysql:5.7
Step3: 檢查 mysql image有沒有下載下來docker images
Step4: docker run -d --name judymysql -e MYSQL_ROOT_PASSWORD=password -p 3306:3306 -v mysql_data:/var/lib/mysql mysql:5.7
部份 | 說明 |
---|---|
--name judymysql |
自己取容器名稱 |
-e MYSQL_ROOT_PASSWORD=填入密碼 |
設定root密碼 |
-p 3306:3306 |
把本機 3306 port 連到容器內的 3306(MySQL port) |
-v mydata:/usr/share/nginx/html |
把 Volume mysql_data 掛載到容器的/var/lib/mysql 資料夾 |
mysql:5.7 |
使用的 image |
備註: 成功後用docker ps
可以看到 judymysql 正在運行
備註: 我自己電腦有安裝MySQL所以3306 port已經被佔據,所以最後我將Step4指令改為 -p 3307:3306
Step5:連接到MySQL測試看看docker exec -it judymysql bash
-> 進入容器mysql -u root -p
-> 在容器內,登入MySQL
(輸入密碼)
成功登入會出現mysql>
這個畫面,有看到的話,恭喜已經連到MySQL資料庫!
Step6: 建立一個測試資料庫CREATE DATABASE docker_test
;SHOW DATABASES;
你會看到docker_test出現在資料庫清單中
Step7: 刪除容器,看看資料是否還存在
首先,先離開MySQL 輸入exit
接著,再離開bash 輸入exit
然後,暫停容器,輸入docker stop judymysql
最後,刪除容器,輸入docker rm judymysql
-> 如此一來,你的容器就不見了,但Volume mysql_data還在
Step8: 重新建立 MySQL 容器(要用同一個Volume)docker run -d --name judymysqlrecreate -e MYSQL_ROOT_PASSWORD=password -p 3307:3306 -v mysql_data:/var/lib/mysql mysql:5.7
Step9: 再進入容器登入MySQLdocker exec -it judymysqlrecreate bash
mysql -u root -p
-> 接著輸入密碼 -> 輸入SHOW DATABASES
-> 看到剛剛建立的docker_test
輸入SHOW DATABASES;
-> 就會看到剛剛建立的docker_test還存在
恭喜!做完這個挑戰不容易,現在已經完全了解Volume
Docker Network 就是讓這些容器可以互相看到彼此、互相傳資料的方式
備註: Docker最常用的是 Network 類型 bridge
Docker default 使用 default bridge
容器之間只能用IP位址,IP位置常常變所以不方便
自己建network就有DNS,很方便互相溝通,且容器之間可以互ping
docker network create mynetwork
-> 建一個新的Network,名字叫mynetworkdocker network ls
-> 確認network有沒有建立成功
docker run -d --name joinmynet1 --network mynetwork nginx
-> 會印出容器IDdocker run -d --name joinmynet2 --network mynetwork nginx
-> 會印出容器IDdocker ps
-> 會看到joinmynet1、joinmynet2都在運行
docker exec -it joinmynet1 bash
-> 進入joinmynet1 容器
apt update
apt install -y iputils-ping
ping joinmynet2
備註: ping不會停下,要用ctrl+c手動中止
今天內容好像太多了,恭喜完成到這邊的人!明天進入Dockerfile打包盡量簡潔一點哈哈。